package fi.jamk.ourcookingapp.backend.architecture.interfaces;

import java.util.List;
import java.util.concurrent.ExecutionException;

import org.json.JSONException;

import fi.jamk.ourcookingapp.backend.exceptions.NoIngredientsException;
import fi.jamk.ourcookingapp.backend.exceptions.NoReceiptException;
import fi.jamk.ourcookingapp.backend.exceptions.NoResultException;
import fi.jamk.ourcookingapp.backend.exceptions.NoStepsException;
import fi.jamk.ourcookingapp.backend.model.Ingredient;
import fi.jamk.ourcookingapp.backend.model.Rating;
import fi.jamk.ourcookingapp.backend.model.Receipt;
import fi.jamk.ourcookingapp.backend.model.Step;
import fi.jamk.ourcookingapp.backend.model.User;

/**
 * Manager for handling functions of receipt.
 * @author Marius
 */
public interface IReceiptManager {

	/**
	 * Deletes a receipt by setting its attribute "deleted" to true.
	 * @param receipt
	 * @return boolean deleted
	 * @throws InterruptedException
	 * @throws ExecutionException
	 * @throws JSONException
	 */
	public boolean deleteReceipt(Receipt receipt) throws InterruptedException, ExecutionException, JSONException;
	
	/**
	 * Updates the given receipt and returns it.
	 * @param receipt
	 * @param clicks 
	 * @param createConns
	 * @return the receipt to be updated
	 * @throws InterruptedException
	 * @throws ExecutionException
	 * @throws JSONException
	 */
	public Receipt updateReceipt(Receipt receipt, boolean clicks) throws InterruptedException, ExecutionException, JSONException;
	
	/**
	 * Creates a new receipt in the database and returns it with its inserted id
	 * @param receipt
	 * @return created Receipt
	 * @throws InterruptedException
	 * @throws ExecutionException
	 * @throws JSONException
	 * @throws NoStepsException 
	 * @throws NoIngredientsException 
	 */
	public Receipt createReceipt(Receipt receipt) throws InterruptedException, ExecutionException, JSONException, NoIngredientsException, NoStepsException;
	
	/**
	 * Filters for the receipt. Options and filter are set by the User
	 * @return List<Receipt> result
	 * @throws InterruptedException
	 * @throws ExecutionException
	 * @throws JSONException
	 * @throws NoReceiptException 
	 */
	public List<Receipt> filter(boolean count) throws InterruptedException, ExecutionException, JSONException, NoReceiptException;
	
	/**
	 * Rating the receipt
	 * @param receipt
	 * @param rating
	 * @return amount rated
	 * @throws InterruptedException
	 * @throws ExecutionException
	 * @throws NumberFormatException
	 * @throws JSONException
	 */
	public double rateReceipt(Receipt receipt, Rating rating) throws InterruptedException, ExecutionException, NumberFormatException, JSONException;
	
	/**
	 * Get all the available ingredients
	 * @return List<Ingredient> result
	 * @throws JSONException
	 * @throws InterruptedException
	 * @throws ExecutionException
	 * @throws NoResultException 
	 */
	public List<Ingredient> getAllIngredients() throws JSONException, InterruptedException, ExecutionException, NoResultException;

	/**
	 * Set value filter for the given key
	 * @param key
	 * @param value
	 */
	public void setFilter(String key, Object value);

	/**
	 * Set value option for the given key
	 * @param key
	 * @param value
	 */
	public void setOption(String key, String value);
	
	/**
	 * Adds the given receipt to the favourite list of the given user
	 * @param receipt
	 * @param user
	 * @throws JSONException
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */
	public void addToFavourite(Receipt receipt, User user) throws JSONException, InterruptedException, ExecutionException;

	/**
	 * Retrieve the list of favourite receipts from the given user
	 * @param user
	 * @return List<Receipt> favourites
	 * @throws JSONException
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */
	public List<Receipt> getFavourites(User user) throws JSONException, InterruptedException, ExecutionException;

	/**
	 * Retrieve a list of ingredients for the given receipt
	 * @param receipt
	 * @return List<Ingredient> result
	 * @throws JSONException
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */
	public List<Ingredient> ingredientsByReceipt(Receipt receipt) throws JSONException, InterruptedException, ExecutionException;

	/**
	 * Retrieve a list of steps for the given receipt
	 * @param receipt
	 * @return List<Step> result
	 * @throws JSONException
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */
	public List<Step> stepsByReceipt(Receipt receipt) throws JSONException, InterruptedException, ExecutionException;

	/**
	 * Removes the given receipt from the favourites list of the user
	 * @param receipt
	 * @param user
	 * @throws JSONException
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */
	public void removeFromFavourite(Receipt receipt, User user) throws JSONException, InterruptedException, ExecutionException;
	
}
